home *** CD-ROM | disk | FTP | other *** search
- The Root of the Problem
- (PC Tech Journal January 1987 by Murray L. Lesser)
-
- Building an intricate graphics program requires evaluation of
- thousands of square roots, but only to integer accuracy. BASIC
- compilers do it the hard way: they convert the integer function
- argument to a single-precision, floating-point number, take the square
- root of that, then convert the floating-point result back into an
- integer.
- ROOT.ASM produces the nearest integer to the actual square root
- of an integer argument. It returns a zero value for a negative
- argument rather than an error. Because the routine has no absolute
- jumps, it could be used to speed up interpreted BASIC if it were
- coded into an integer array. ROOT also can be BLOADed into an
- interpreted BASIC program.
- An example of ROOT in use under Microsoft's QuickBASIC is given
- in ROOTTEST.ASM. ROOTTEST runs four times faster using ROOT than it
- does using QuickBASIC's floating-point, square-root function.
-
- ; ROOT.ASM -- an assembled fast integer square root subroutine to be
- ; linked to Microsoft compiled BASIC programs.
- ; Call with ROOT(x,y) where x is an integer expression
- ; y is an integer variable
- ; The square root of x will be returned in y. (Negative input will
- ; return a zero.)
- ; ROOT is a binary adaptation of the synthetic division square root
- ; procedure shown in the paper by J. E. Meggit, "Pseudo Division and
- ; Pseudo Multiplication Processes." The IBM Journal of Research and
- ; Development, vol. 6, no. 2 (April 1962), pp. 210-226.
- ; Written by M. L. Lesser, April 13, 1986.
- ; Assembled with Microsoft MASM version 4.00
- ;
- DATA SEGMENT BYTE PUBLIC 'CODE'
- DATA ENDS
- DGROUP GROUP DATA
-
- SQRT SEGMENT BYTE PUBLIC 'CODE'
- ASSUME CS:SQRT,DS:DGROUP
- PUBLIC ROOT
-
- ROOT PROC FAR
- PUSH BP
- MOV BP,SP
- MOV BX,8[BP]
- MOV AX,[BX]
- XOR DX,DX
- MOV CX,8
- MOV BX,4000H
- MOV DI,8000H
- MOV SI,2000H
- CMP AX,DX
- JLE DONE
- DOIT: SHL DX,1
- CMP AX,BX
- JL NEXT
- INC DX
- SUB AX,BX
- ADD BX,DI
- NEXT: SUB BX,SI
- SHR DI,1
- SHR DI,1
- SHR SI,1
- SHR SI,1
- SHR BX,1
- LOOP DOIT
- CMP AX,BX
- JLE DONE
- INC DX
- DONE: MOV BX,6[BP]
- MOV [BX],DX
- POP BP
- RET 4
-
- ROOT ENDP
- SQRT ENDS
- END
-
-
- ROOTTTEST.ASM:
-
- ' TEST.BAS: An example of the use of ROOT.ASM.
- ' Compile with a Microsoft BASIC compiler and link to ROOT.OBJ
-
- defint a-c
- defsng d
- for a=0 to 32766
- call root(a,b)
- let d=sqr(a)
- let c=d
- gosub 1000
- if inkey$=chr$(3) then end
- next a
- let a=32767
- call root(a,b)
- let=sqr(a)
- let c=d
- gosub 1000
- end
- 1000 print a,b,c,d
- if b<>c then while inkey$<>"":wend
- return
-
- -----------------------------------------------------------------
- Using PUT and GET on the IBM PC
- (COMPUTE! Magazine March 1987 by Rafael Gonzalez)
-
- IBM BASIC has two commands -- PUT and GET -- that make it easy for
- you to animate figures. These powerful commands appear frequently in
- games, but they have many other uses, as well. (PUT and GET are also
- used for random file operations, but with a different syntax.)
- You might think of PUT and GET as "bit pump" operations which move
- bits from memory onto the screen (PUT) and from the screen into memory
- (GET). GET reads the colors of the points within a rectangular screen
- area and stores that information in an array. The basic syntax for the
- command is:
-
- GET(x1,y1)-(x2,y2),array
-
- Each GET command includes two pairs of screen coordinates and an
- array name. The coordinates define the area to be captured and the
- array name tells BASIC where to store the image. The first pair of
- coordinates (x1 and y1 in this example) defines the upper left corner
- of the rectangle. The second pair (x2 and y2) defines the rectangle's
- lower right corner. (This is identical to the method used to define a
- rectangle in a LINE command with the B option.)
- The array used with GET must be of the numeric type. It can be
- any precision, although integer arrays are commonly used. Except for
- very small shapes, you must DIMension the array before using it. This
- task, in turn, requires that you calculate how big the array should be.
- The BASIC formula for calculating the array size is:
-
- 4 + INT((x * bits per pixel + 7) / 8) * y
-
- In this case, x and y are the lengths of the horizontal and
- vertical sides of the rectangle, respectively. The bits per pixel
- value is equal to 4 in low resolution, 2 or 4 in medium resolution,
- and 1 or 2 in high resolution, depending upon the current screen mode.
- For example, suppose you want to capture a 10 x 12-pixel image in
- medium resolution with GET. The number of bytes required is 4 + INT
- ((10 * 2 + 7) / 8) * 12, or 40 bytes. Next, you must consider how many
- bytes each element of the array contains. This factor depends on the
- array's precision. This table shows how many bytes are contained in
- each element of an integer, single-precision, or double-precision array:
-
- Bytes Array Type
-
- 2 Integer
- 4 Single-precision
- 8 Double-precision
-
- Since the example shape requires 40 bytes, it can be stored in an
- integer array containing 20 elements, a single-precision array
- containing 8 elements, or a double-precision array containing 5
- elements. It's important to dimension an array of the proper size,
- since BASIC stops with the error message, "Illegal function call" if
- the array is too small. Using an overly large array doesn't do any
- harm. However, grossly overlarge arrays waste memory.
- The PUT command is the opposite of GET: Once you have stored a
- shape with GET, PUT can place the shape anywhere on the screen. The
- syntax is:
-
- PUT (x,y),array,action
-
- In this example, x and y set the coordinates where the upper left
- corner of the image will be placed and the variable array identifies
- the array which contains the shape.
- The optional parameter action lets you select different modes for
- a PUT operation. This part of the statement may consist of the word
- PSET, PRESET, XOR, OR, or AND. If you omit the action parameter, PUT
- defaults to XOR mode.
- The PUT mode determines how the placed shape interacts with
- graphics data that's already present in the same screen area. Type in
- and save the example program, then run it to see how the mode affects
- PUT. The program draws a multicolored background and PUTs the same
- sahep on the screen in five different places using all of the different
- modes. Here's what each mode does:
-
- PSET. In this mode, PUT simply stores the captured data on
- the screen, overwriting any graphics data that previously existed in
- the same area. In the example program the transferred image completely
- replaces the contents of that screen area.
-
- PRESET. This mode replaces all existing data, just as in PSET
- mode, but the image is reversed. That is, a value of 0 in the array
- causes the corresponding point on the screen to have attribute number
- 3, and vice versa. A value of 1 in the array causes the corresponding
- point on the screen to have attribute 2, and so forth. In the program,
- this mode causes the image to have a different color.
-
- AND. The AND mode sets pixels only at points that already
- contain data matching corresponding data in the transferred image.
- In the example program, only pixels that are originally cyan remain
- in the final image.
-
- OR. This mode superimposes an image onto existing data.
-
- XOR. The XOR mode is most often used for animation. When a
- pixel in the PUT image overlays a point on the screen that contains
- data, the point is inverted. This feature allows you to move a shape
- nondestructively over a complex background: When an image is PUT
- against a background twice, it restores the original data unchanged.
-
- The following tables show how AND, XOR, and OR modes affect
- screen attributes in medium-resolution mode (SCREEN 1 or SCREEN 4).
-
- AND
- --- Array Value
- screen 0 1 2 3
-
- 0 0 0 0 0
- 1 0 1 0 1
- 2 0 0 2 2
- 3 0 1 2 3
-
- OR
- -- Array Value
- screen 0 1 2 3
-
- 0 0 1 2 3
- 1 1 1 3 3
- 2 2 3 2 3
- 3 3 3 3 3
-
- XOR
- --- Array Value
- screen 0 1 2 3
-
- 0 0 1 2 3
- 1 1 0 3 2
- 2 2 3 0 1
- 3 3 2 1 0
-
- The example program also demonstrates simple animation with PUT
- in XOR mode. After the five large shapes are drawn, it sends a small
- shape bouncing around the screen. The process of animation involves
- four basic steps:
- 1. Calculate a new position for the shape.
- 2. PUT the shape on the screen at its previous location (to
- erase the old image).
- 3. PUT the shape in its new position.
- 4. Return to step 1.
- Before you enter the loop, you must have PUT the shape on the
- screen once, so that the PUT in step 2 will erase it. This preliminary
- step is performed in line 440 of the program. Line 450 saves the old
- position of the shape in OLDX and OLDY before a new position is
- calculated in lines 460-490.
- BASIC animation with PUT always involves a certain amount of
- flickering, which results from the delay between the time the old shape
- is erased and the new one is drawn. To minimize flicker, you should
- perform the two PUTs as close together as possible. This reduces the
- amount of time that the shape is invisible. The example program
- accomplishes this by putting both PUT statements on the same line.
- The first statement in line 510 erases the old image, and the second
- statement draws the new one. The do-nothing loop in line 520 holds
- the new image on the screen for a short interval to alleviate flicker
- even further. Most programs won't need an explicit delay, since the
- program will be doing time-consuming tasks between each redraw.
- Once you understand the basics of GET and PUT, you may find many
- uses for these commands. A drawing program, for instance, may include
- a feature allowing you to copy one screen area to another. If you
- capture the indicated area with GET, it is effectively saved in an
- offscreen buffer, and can be replaced at any time with a simple PUT
- command. In fact, if sufficient memory is available, you can even
- GET an entire screen.
- To see the effect of a full-screen GET, press any key while the
- small box is moving on the screen. The program saves the current
- screen in the array SCRN2%, then PUTs on the screen an image previously
- stored in the array SCRN1%. Immediately thereafter, it restores the
- current image by PUTting the SCRN2% image back on the screen. As you
- can see, significant delays result from manipulating images of this
- size.
-
- 100 SCREEN 1:KEY OFF:RANDOMIZE TIMER
- 110 LINE (60,60)-(120,120),1,BF
- 120 X=61:Y=61
- 130 BITSPERPIXEL=2
- 140 NUM=4+INT((X*BITSPERPIXEL+7)/8)*Y
- 150 DIM LARGE%(NUM/2),SMALL%(NUM/4)
- 160 X=320:Y=200
- 170 NUM=4+INT((X*BITSPERPIXEL+7)/8)*Y
- 180 DIM SCRN1%(NUM/2),SCRN2%(NUM/2)
- 190 GET (60,60)-(120,120),LARGE%
- 200 GET (60,60)-(90,90),SMALL%
- 210 CLS
- 220 FOR COL=1 TO 3:FOR J=1 TO 50
- 230 X=INT(RND*319):Y=INT(RND*199)
- 240 PSET (X,Y),COL:NEXT:NEXT
- 250 GET (0,0)-(319,199),SCRN1%
- 260 FOR J=40 TO 140 STEP 10
- 270 LINE (0,J)-(320,J+1),1,BF
- 280 LINE (0,J+2)-(320,J+3),2,BF
- 290 LINE (0,J+4)-(320,J+5),3,BF
- 300 NEXT
- 310 PUT (30,20),LARGE%,PSET
- 320 PUT (120,20),LARGE%,PRESET
- 330 PUT (210,20),LARGE%,AND
- 340 PUT (70,110),LARGE%,OR
- 350 PUT (180,110),LARGE%,XOR
- 360 LOCATE 2,6:PRINT "PSET"
- 370 LOCATE 2,17:PRINT "PRESET"
- 380 LOCATE 2,29:PRINT "AND"
- 390 LOCATE 23,13:PRINT "OR"
- 400 LOCATE 23,26:PRINT "XOR"
- 410 X=10:Y=50:DX=2:DY=2
- 420 RLIM=320-32:LLIM=0
- 430 ULIM=0:DLIM=200-32
- 440 PUT (X,Y),SMALL%
- 450 OLDX=X:OLDY=Y
- 460 IF INKEY$<>"" THEN GET (0,0)-(319,199),SCRN2%:PUT (0,0),SCRN1%,AND:PUT (0,0),SCRN2%,PSET
- 470 X=X+DX
- 480 IF X=>RLIM OR X<=LLIM THEN DX=-DX
- 490 Y=Y+DY
- 500 IF Y<=ULIM OR Y>=DLIM THEN DY=-DY
- 510 PUT (OLDX,OLDY),SMALL%:PUT (X,Y),SMALL%
- 520 FOR J=0 TO 80:NEXT
- 530 GOTO 450
-
- -----------------------------------------------------------------
- Sowing a Random FIELD
- (PC World March 1987 The Help Screen)
-
- BASIC 2.0 supports random file record lengths up to 32,767 bytes.
- The problem is using a random file structure to store 2048 single-
- precision values (8192 bytes) per record.
- The trick is to use multiple FIELD statements. Consider:
-
- 1 OPEN "FOO" AS #1
- 2 FIELD 1,100 AS A$,200 AS B$
- 3 FIELD 1,300 AS DUMMY$,40 AS C$
-
- Note that line 3 uses a dummy variable to move the file buffer's
- pointer past the area assigned for A$ and B$ (100 + 200 = 300) so
- that the field definitions of line 2 are not lost.
-